package com.itheima.proxy;

import com.itheima.service.UserService;
import com.itheima.service.impl.UserServiceImpl;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class jdkProxyDemo {
    public static void main(String[] args) {
        //目标对象
        //代理对象如果是方法, 那么目标对象就是实现该方法的路径名
        //例如这次案例,目标对象可以是UserService,也可以是UserServiceImpl
        final UserServiceImpl usi = new UserServiceImpl();

        //创建代理对象(代理对象产生的对象地址是com.sun.proxy.$ProxyXXX)
        /*注意!!不能用目标对象接代理对象,目标对象和代理对象属于同级,
            如果用目标对象接代理对象,会报错:代理对象转换不了目标对象*/

        UserService us = (UserService) Proxy.newProxyInstance(usi.getClass().getClassLoader(), usi.getClass().getInterfaces(), new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object obj = null;
                //选择性增强某个方法,或不增强某个方法
                if ("speak".equals(method.getName())){
                    return method.invoke(usi,args);
                }else {
                    try {
                        System.out.println("前置增强");//开启事务
                        obj = method.invoke(usi, args);//执行usi对象上带有args参数列表的method方法
                        System.out.println("后置增强");//提交事务
                    } catch (Exception e) {
                        System.out.println("异常增强");//回滚事务
                    } finally {
                        System.out.println("最终增强");//释放资源
                    }
                }
                return obj;//代表的是执行目标方法对象的返回值
            }
        });
        //通过代理对象调用具体方法
        us.say();
    }
}
